<template>
  <div class="common-tree-container">
    <div class="left-container-wrap" ref="leftContainerWrap" id="common-tree-left-container-wrap">
        <div class="search-input-wrap">
          <el-input size="small" v-model="condition" clearable></el-input>
          <div class="btn-wrap">
            <el-button size="small" circle type="primary" icon="el-icon-search" @click="filterTreeData"/>
            <i :class="[treeExpand ? 'el-icon-remove' : 'el-icon-circle-plus', 'expand-tree']" @click="changeTreeExpand"></i>
          </div>
        </div>
        <el-scrollbar>
          <el-tree v-if="!loading"
            :lazy="lazy"
            :data="data"
            :props="props"
            ref="tree"
            :load="loadData"
            node-key="id"
            :current-node-key="currentKey"
            :default-expand-all="treeExpand"
            highlight-current
            @node-click="handleNodeClick"
            :render-content="renderContent"></el-tree>
          <div v-if="loading" v-loading="loading"></div>
        </el-scrollbar>
      </div>
    <div class="el-divider el-divider--vertical" v-adjust-width="'#common-tree-left-container-wrap'"></div>
    <div class="right-data" ref="treeRightData">
      <div id="model-info-option">
        <div class="mio-title" ref="mioTitle">
          <div class="mio-title-head">
            <i :class="[currentClickNodeData ? currentClickNodeData.icon : '', 'mio-title-icon']"
               v-if="currentClickNodeData && currentClickNodeData.icon && currentClickNodeData.iconType === 'element-ui'"/>
            <span>{{currentClickNodeName}}</span>
            <span class="option-btn-group">
              <el-tooltip :content="isLabel() ? '新建标签' : '新建子模型'" placement="top" effect="light" :hide-after="500">
                <i class="el-icon-plus" style="color: green;" @click="openDialog(false)"></i>
              </el-tooltip>
              <el-tooltip :content="isLabel() ? '编辑标签' : '编辑模型'" placement="top" effect="light" v-if="currentClickNodeName" :hide-after="500">
                <i class="el-icon-edit" style="color: #43b8c2;" @click="editLabel"></i>
              </el-tooltip>
              <el-tooltip :content="isLabel() ? '删除标签' : '删除模型'" placement="top" effect="light" v-if="isLabel() || (currentClickNodeData && !currentClickNodeData.published)" :hide-after="500">
                <i class="el-icon-close" style="color: red;" @click="deleteLabel"></i>
              </el-tooltip>
            </span>

            <div class="fr r-btn-group">
              <el-tooltip content="查看发布信息" placement="top" effect="light" :hide-after="500">
                <el-button icon="el-icon-view" type="warning" plain circle @click="viewPublishedInfo" size="mini"></el-button>
              </el-tooltip>

              <el-tooltip content="模型发布" placement="top" effect="light" :hide-after="500" v-if="showPublishBtn">
                <el-button icon="el-icon-check" type="success" plain circle @click="publishModel" size="mini"></el-button>
              </el-tooltip>

              <el-tooltip content="新建根标签" placement="top" effect="light" :hide-after="500" v-if="isLabel()">
                <el-button icon="el-icon-plus" type="warning" plain circle @click="openDialog(true)" size="mini"></el-button>
              </el-tooltip>

              <el-tooltip content="加载模型标签" placement="top" effect="light" :hide-after="500">
                <el-button icon="el-icon-receiving" type="primary" plain circle @click="loadModelLabels" size="mini"></el-button>
              </el-tooltip>
            </div>
          </div>
          <div class="mio-title-tab">
            <el-tabs tab-position="top" style="height: 200px;" @tab-click="changeTab" v-model="currentSelectedTabName">
              <el-tab-pane label="基本信息" name="baseInfo"></el-tab-pane>
              <el-tab-pane label="子项列表" name="childrenList"></el-tab-pane>
              <el-tab-pane label="模型属性列表" name="attributeList" v-if="!isLabel()"></el-tab-pane>
              <el-tab-pane label="模型表单配置" name="modelFormConfig" v-if="!isLabel()"></el-tab-pane>
            </el-tabs>
          </div>
        </div>
        <div class="mio-data-content" :style="{'max-height': dataContentHeight + 'px', height: dataContentHeight + 'px'}">
          <router-view :key="$route.fullPath" v-show="currentClickNodeData"></router-view>
        </div>
      </div>
    </div>

    <label-form :visible="showCreateForm" @removed="closeLabelFormDialog" v-if="showCreateForm && isLabel()"
                         :item-info="currentClickNodeData" :root="root" :defaultWeight="weight"
                         :edit="edit" @updateLabelTree="updateLabelTree">
    </label-form>

    <model-definition-form :visible="showCreateForm" @removed="closeLabelFormDialog" v-if="showCreateForm && !isLabel()"
                           :item-info="currentClickNodeData" :defaultWeight="weight"
                           :edit="edit" @updateLabelTree="updateLabelTree">
    </model-definition-form>

    <view-published-info :visible="viewPublished" @removed="closeLabelFormDialog" v-if="viewPublished">
    </view-published-info>
  </div>
</template>

<script>

import LabelForm from '@/components/model/LabelForm'
import ModelDefinitionForm from '@/components/model/ModelDefinitionForm'
import ViewPublishedInfo from '@/components/model/ViewPublishedInfo'
import {getModelRootTreeData, getModelChildrenLabelData, deleteLabel, loadModelLabels, filterLabels} from '@/js/api/model/modelTree'
import {getModelDefinitionChildrenData, deleteModelDefinition, publishModel} from '@/js/api/model/modelDefinition'
import routerNames from '@/router/routerNames'

const TAB_NAME_BASE_INFO = 'baseInfo'
const TAB_NAME_CHILDREN_LIST = 'childrenList'
const TAB_NAME_ATTR_LIST = 'attributeList'
const TAB_NAME_MODEL_FORM_CONFIG = 'modelFormConfig'

export default {
  name: 'CommonTree.vue',
  components: {
    LabelForm,
    ModelDefinitionForm,
    ViewPublishedInfo
  },
  data(){
    return {
      props: {
        children: 'children',
        isLeaf: 'leaf'
      },
      data: [],
      lazy: true,
      condition: '',
      treeExpand: false,
      currentClickNodeName: '',
      currentClickNodeData: undefined,
      currentClickNode: undefined,
      dataContentHeight: 100,
      showCreateForm: false,
      edit: false,
      loading: true, // 正在加载树数据
      currentKey: '',
      currentSelectedTabName: TAB_NAME_BASE_INFO,
      preSelectedTabName: TAB_NAME_BASE_INFO,
      disabled: false,
      // 标记是否创建根标签
      root: false,
      // 默认权重
      weight: 0,
      viewPublished: false
    }
  },
  methods: {
    handleNodeClick(data, node, notChangeRouter) {
      console.log(data, 22)

      this.currentClickNodeData = data
      this.currentClickNodeName = data?.name || ''
      this.currentClickNode = node

      if (node && node.parent){
        // 展开父节点
        node.parent.expanded = true
      }

      if (!this.currentSelectedTabName){
        this.currentSelectedTabName = TAB_NAME_BASE_INFO
        this.preSelectedTabName = this.currentSelectedTabName
      }
      const isLabelTab = this.currentSelectedTabName === TAB_NAME_BASE_INFO ||
        this.currentSelectedTabName === TAB_NAME_CHILDREN_LIST
      // 如果路由需要跳转获，所选的tab页标签没有，路由则重新跳转
      if (!(notChangeRouter === true) || (isLabelTab && this.isLabel())){
        this.changeRouter()
      }
    },
    changeRouter(){
      if (TAB_NAME_BASE_INFO === this.currentSelectedTabName){
        // 路由跳转
        if (this.isLabel()){
          this.pushTo(routerNames.modelLabelInfo)
        } else {
          this.pushTo(routerNames.modelConfigInfo)
        }
      } else if (TAB_NAME_CHILDREN_LIST === this.currentSelectedTabName){
        // 路由跳转
        if (this.isLabel()){
          this.pushTo(routerNames.modelLabelChildren)
        } else {
          this.pushTo(routerNames.modelDefinitionChildren)
        }
      } else {
        if (this.isLabel()){
          this.pushTo(routerNames.modelLabelInfo)
          this.preSelectedTabName = this.currentSelectedTabName = TAB_NAME_BASE_INFO
        } else {
          if (TAB_NAME_ATTR_LIST === this.currentSelectedTabName){
            this.pushTo(routerNames.modelAttrList)
          } else if (TAB_NAME_MODEL_FORM_CONFIG === this.currentSelectedTabName){
            this.pushTo(routerNames.modelFormConfig)
          }
        }
      }
    },
    pushTo(routerName){
      this.$router.push({
        name: routerName,
        params: {id: this.currentClickNodeData?.id || ''},
        query: {t: Date.now(), tabName: this.currentSelectedTabName}
      })
    },
    isLabel(){
      return this.currentClickNodeData?.classId !== 'ModelDefinition'
    },
    filterTreeData(){
      const condition = this.condition.trim()
      this.lazy = condition.length === 0
      this.treeExpand = !this.lazy
      if (this.lazy){
        this.getLabelTreeData()
      } else {
        this._filterLabels()
      }
    },
    async _filterLabels(){
      this.loading = true
      const treeData = await filterLabels(this.condition.trim())
      if (treeData.errorMsg){
        this.$msgAlert(treeData.errorMsg, 'error')
      } else {
        this.data = treeData.data.data
        this.currentClickNodeData = treeData.data.currentData
        this.currentKey = this.currentClickNodeData?.id
        this.handleNodeClick(this.currentClickNodeData, undefined)
      }
      this.loading = false
    },
    changeTreeExpand(){
      this.treeExpand = !this.treeExpand
      this.changeTreeNodeStatus(this.$refs.tree.store.root)
    },
    // 改变节点的状态(展开，收起)
    changeTreeNodeStatus(node) {
      node.expanded = this.treeExpand
      for (let i = 0; i < node.childNodes.length; i++) {
        // 改变节点的自身expanded状态
        node.childNodes[i].expanded = this.treeExpand
        // 遍历子节点
        if (node.childNodes[i].childNodes.length > 0) {
          this.changeTreeNodeStatus(node.childNodes[i])
        }
      }
    },
    // 渲染节点内容
    renderContent(h, { node, data, store }){
      return (
        <span class="tree-node-data">
          <span>{data.icon && data.iconType === 'element-ui' ? <i class={data.icon + ' tree-node-icon'}/> : ''}</span>
          <span>{data.name}</span>
        </span>)
    },
    getDataContentHeight(){
      if (this.$refs.mioTitle){
        this.dataContentHeight = this.$refs.treeRightData.offsetHeight - this.$refs.mioTitle.offsetHeight
      }
    },
    closeLabelFormDialog(){
      this.showCreateForm = false
      this.viewPublished = false
    },
    setCurrentClickNode(){
      if (!this.currentClickNodeData || this.currentClickNode) return
      this.currentClickNode = this.$refs.tree.getNode(this.currentClickNodeData.id)
    },
    updateLabelTree(data){
      this.setCurrentClickNode()
      if (this.edit){
        if (!this.currentClickNodeData) return
        // 更新节点数据
        const keys = Object.keys(data)
        const nodeData = this.currentClickNode.data
        keys.forEach((key) => {
          // eslint-disable-next-line no-prototype-builtins
          if (!nodeData.hasOwnProperty(key)){
            this.$set(nodeData, key, data[key])
          } else {
            nodeData[key] = data[key]
          }
        })
        this.handleNodeClick(data, this.currentClickNode)
      } else {
        this.$refs.tree.append(data, this.root ? undefined : this.currentClickNode)
      }
    },
    openDialog(root){
      this.showCreateForm = true
      this.edit = false
      this.root = !!root

      this.setCurrentClickNode()
      let _data
      // 计算默认权重
      if (this.root){
        _data = this.data && this.data.length > 0 ? this.data[this.data.length - 1] : undefined
      } else {
        _data = this.currentClickNode?.childNodes
        _data = _data.length > 0 ? _data[_data.length - 1].data : undefined
      }
      this.weight = _data ? _data.weight + 1 : 0
    },
    editLabel(){
      this.showCreateForm = true
      this.edit = true
    },
    async getLabelTreeData(){
      this.loading = true
      const treeData = await getModelRootTreeData()
      if (treeData.errorMsg){
        this.$msgAlert(treeData.errorMsg, 'error')
      } else {
        this.data = treeData.data
      }
      this.currentKey = this.data.length > 0 ? this.data[0].id : ''
      this.handleNodeClick(this.currentKey ? this.data[0] : undefined, undefined)
      this.loading = false
    },
    async getChildrenLabelData(nodeData, resolve){
      let treeData
      if (nodeData.classId !== 'ModelDefinition') {
        treeData = await getModelChildrenLabelData(nodeData.id)
      } else {
        treeData = await getModelDefinitionChildrenData(nodeData.id)
      }
      let data = []
      if (treeData.errorMsg){
        this.$msgAlert(treeData.errorMsg, 'error')
      } else {
        data = treeData.data
      }
      resolve(data)
    },
    loadData(node, resolve){
      if (node.level === 0) {
        return resolve(this.data)
      }
      this.getChildrenLabelData(node.data, resolve)
    },
    initCurrentDataByNodeKey(nodeKey){
      if (this.$refs.tree){
        if (!nodeKey){
          this.handleNodeClick(this.currentClickNodeData, this.currentClickNode, false)
        } else {
          let node = this.$refs.tree.getNode(nodeKey)
          if (!node && this.data.length > 0) {
            node = this.$refs.tree.getNode(this.data[0].id)
            nodeKey = this.data[0].id
          }
          this.$refs.tree.setCurrentKey(nodeKey)
          if (node) {
            this.handleNodeClick(node.data, node, false)
          }
        }
      }
    },
    async _deleteLabel(){
      let response
      if (this.isLabel()) {
        response = await deleteLabel(this.currentClickNodeData.id)
      } else {
        response = await deleteModelDefinition(this.currentClickNodeData.id)
      }
      if (response.errorMsg){
        this.$msgAlert(response.errorMsg, 'error')
      } else {
        this.$tips('删除成功')
        // 删除节点
        this.$refs.tree.remove(this.currentClickNode)

        let nodeKey = this.currentClickNodeData.parentId
        let node = this.$refs.tree.getNode(nodeKey)
        if (!node){
          node = this.$refs.tree.store?.root?.childNodes?.[0]
          nodeKey = node?.data || ''
        }
        this.$refs.tree.setCurrentKey(nodeKey)
        this.handleNodeClick(node?.data || undefined, node)
      }
    },
    deleteLabel(){
      this.setCurrentClickNode()
      if (!this.currentClickNode){
        this.$msgAlert('请选择要删除的数据', 'error')
        return
      }
      // 判断是否有子节点，有不能删除
      if (this.currentClickNode.childNodes.length > 0) {
        this.$msgAlert('要删除的数据有子节点，不能删除', 'error')
        return
      }
      this.$myConfirm('是否确定要删除该条数据？', this._deleteLabel)
    },
    changeTab(v){
      if (this.preSelectedTabName === v.name) return
      this.preSelectedTabName = this.currentSelectedTabName
      this.changeRouter()
    },
    async loadModelLabels(){
      this.disabled = true
      const mask = this.$appLoading('数据处理中。。。', '#main-container')
      const response = await loadModelLabels()
      if (response.errorMsg){
        this.$msgAlert(response.errorMsg, 'error')
        mask.close()
      } else {
        this.disabled = false
        this.$tips('加载成功')
        mask.close()
        this.lazy = true
        this.condition = ''
        this.treeExpand = false
        await this.getLabelTreeData()
      }
    },
    publishModel(){
      if (!this.currentClickNodeData){
        this.$tips('请选择要发布的模型！', 'error')
        return
      }
      this.$myConfirm('是否确定发布？', async() => {
        const mask = this.$appLoading('数据处理中。。。', '#main-container')
        const response = await publishModel(this.currentClickNodeData.id)
        if (response.errorMsg){
          this.$tips(response.errorMsg, 'error')
        } else {
          this.currentClickNodeData.published = true
          this.handleNodeClick(this.currentClickNodeData, this.currentClickNode)
          this.$tips('模型发布成功')
        }
        mask.close()
      })
    },
    viewPublishedInfo(){
      this.viewPublished = true
    }
  },
  computed: {
    showPublishBtn(){
      return !this.isLabel() && this.currentClickNodeData?.published === false
    }
  },
  created(){
    this.getLabelTreeData()
  },
  mounted(){
    this.$nextTick(() => {
      this.getDataContentHeight()
    })
    window.addEventListener('resize', this.getDataContentHeight)
  },
  destroyed(){
    window.removeEventListener('resize', this.getDataContentHeight)
  },
  watch: {
    $route(v, o){
      this.currentSelectedTabName = v.query.tabName
      this.preSelectedTabName = this.currentSelectedTabName
      const id = v.params?.id || ''
      if (this.currentClickNodeData?.id === id){
        return
      }
      this.initCurrentDataByNodeKey(id)
    }
  }
}
</script>

<style lang="less">
  .common-tree-container{
    height: 100%;
    display: flex;
    .left-container-wrap{
      position: relative;
      width: 200px;
      flex-shrink: 0;
      display: flex;
      flex-direction: column;
      .search-input-wrap{
        padding: 0 5px 5px 5px;
        flex-shrink: 0;
        display: flex;
        align-items: center;
        justify-content: space-between;
        .el-input__inner{
          padding: 0 5px;
        }
        .btn-wrap{
          margin-left: 5px;
          display: flex;
          flex-shrink: 0;
          align-items: center;
          .expand-tree{
            color: #cccccc;
            font-size: 25px;
            margin-left: 5px;
            cursor: pointer;
          }
        }
      }
      .el-scrollbar{
        flex: 1;
        background-color: #f0f0f0;
        .el-scrollbar__wrap{
          overflow-x: hidden;
          .el-tree{
            background-color: #f0f0f0;
            .tree-node-data{
              .tree-node-icon{
                margin-right: 5px;
              }
            }
            .el-tree-node {
              >.el-tree-node__content{
                >.tree-node-data{
                  background-color: inherit;
                }
              }
            }
          }

          .el-loading-mask{
            top: 50px;
          }
        }
      }
    }

    .el-divider {
      height: inherit;
      width: 2px;
      flex-shrink: 0;
      cursor: col-resize;
      margin: 0 4px;
    }

    .right-data{
      flex: 1;
      padding-left: 2px;
      overflow-x: auto;
      #model-info-option{
        display: flex;
        flex-direction: column;
        .mio-title{
          flex-shrink: 0;
          .mio-title-head{
            font-size: 20px;
            font-weight: bold;
            color: #002d93;
            background-color: #72d19c0f;
            padding: 15px 0 15px 10px;
            .mio-title-icon{
              margin-right: 5px;
            }
            .option-btn-group{
              margin-left: 30px;
              i{
                font-weight: 700;
                font-size: 20px;
                margin-right: 15px;
                cursor: pointer;
              }
            }
            .r-btn-group{
              margin-right: 15px;
              .el-button{
                font-weight: 700;
                font-size: 14px;
                color: #740e0e;
                i{
                  font-weight: 700;
                }
                .el-icon-check{
                  color: green;
                }
              }
            }
          }
          .mio-title-tab{
            height: 40px;
            overflow: hidden;
            .el-tabs{
              .el-tabs__item{
                font-weight: 700;
              }
            }
          }
        }
        .mio-data-content{
          flex: 1;
          overflow: hidden;
        }
      }
    }
  }
</style>
